/*****************************************************************************
 * Copyright (c) 2010 -, Anders All rights reserved
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *  Contact: Anders Uddenberg (anders.uddenberg@gmail.com)
 * 
 *
 ****************************************************************************/
package org.easypr.organizer.client.presenter;

import java.util.ArrayList;
import java.util.Date;


import org.easypr.organizer.client.BackboneServiceAsync;
import org.easypr.organizer.client.MyUserService;
import org.easypr.organizer.client.MyUserServiceAsync;
import org.easypr.organizer.client.event.DisplayInformationEvent;
import org.easypr.organizer.shared.MyContact;
import org.easypr.organizer.shared.MyMeeting;
import org.easypr.organizer.shared.MyUser;


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

// TODO: Auto-generated Javadoc
/**
 * The Class DashboardPresenter.
 */
public class DashboardPresenter implements Presenter {

	/**
	 * Define the interface the view needs to implement.
	 * 
	 * @author Anders
	 */
	public interface Display {
		
		/**
		 * Sets the data.
		 *
		 * @param contacts the new data
		 */
		void setData(ArrayList<MyContact> contacts);

		/**
		 * As widget.
		 * 
		 * @return the widget
		 */
		Widget asWidget();
		
		/**
		 * Gets the meeting contact.
		 *
		 * @return the meeting contact
		 */
		MyContact getMeetingContact();
		
		/**
		 * Gets the meeting date.
		 *
		 * @return the meeting date
		 */
		TextBox getMeetingDate();
		
		/**
		 * Gets the meeting notes.
		 *
		 * @return the meeting notes
		 */
		TextArea getMeetingNotes();
		
		/**
		 * Gets the meeting button.
		 *
		 * @return the meeting button
		 */
		Button getMeetingButton();
		
		/**
		 * Gets the contacts table.
		 *
		 * @return the contacts table
		 */
		FlexTable getContactsTable();
		
		/**
		 * Show add new meeting.
		 *
		 * @param contact the contact
		 */
		void showAddNewMeeting(MyContact contact);
		
		/**
		 * Show meeting saved.
		 *
		 * @param meeting the meeting
		 */
		void showMeetingSaved(MyMeeting meeting);
		
		/**
		 * Gets the import link.
		 *
		 * @return the import link
		 */
		Anchor getImportLink();
		
	}

	/** The event bus. */
	private final HandlerManager eventBus;
	
	/** The display. */
	private final Display display;

	/** The user. */
	private MyUser user;
	
	/** The backbone rpc. */
	private BackboneServiceAsync backboneRPC;
	
	/**
	 * Instantiates a new menu presenter.
	 * 
	 * @param eventBus the event bus
	 * @param view the view
	 */
	public DashboardPresenter(HandlerManager eventBus, Display view) {
		this.eventBus = eventBus;
		this.display = view;
	}
	
	/**
	 * Instantiates a new dashboard presenter.
	 *
	 * @param backboneRPC the backbone rpc
	 * @param eventBus the event bus
	 * @param view the view
	 * @param user the user
	 */
	public DashboardPresenter(BackboneServiceAsync backboneRPC, HandlerManager eventBus, Display view, MyUser user) {
		this.backboneRPC = backboneRPC;
		this.eventBus = eventBus;
		this.display = view;
		this.user = user;
	}

	/* (non-Javadoc)
	 * @see org.easypr.organizer.client.presenter.Presenter#go(com.google.gwt.user.client.ui.HasWidgets)
	 */
	@Override
	public void go(HasWidgets container) {
		container.clear();
		container.add(display.asWidget());
		bind();
		updateContent();
	}

	
	
	/**
	 * Bind.
	 */
	private void bind() {
		display.getImportLink().addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {

				AsyncCallback<String> callback = new AsyncCallback<String>() {
					public void onFailure(Throwable caught) {
						eventBus.fireEvent(new DisplayInformationEvent("Unable to proceed with the request!", DisplayInformationEvent.Severity.FAILURE));
					}
					
					public void onSuccess(String url) {
						Window.Location.replace(url);
					}
				};
				if(user.getAccessToken() != null && user.getAccessToken().length() > 0) {
					// We already have an access token. Lets just redirect
					History.newItem("import");
				} else {
					
					String url = Window.Location.getHref();
					url = url.substring(7);
					url = url.substring(0, url.indexOf("/"));
					url = "http://"+url+"/oauth";
					backboneRPC.getOAuthRequestURL(user, url, callback);
				}
			}
		});
		
		
		display.getContactsTable().addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Cell cell = display.getContactsTable().getCellForEvent(event);
				long contactid = Long.parseLong(cell.getElement().getId());
				
				// fetch the contact
				AsyncCallback<MyContact> callback = new AsyncCallback<MyContact>() {
					public void onFailure(Throwable caught) {
						eventBus.fireEvent(new DisplayInformationEvent("Unable to proceed with the request!", DisplayInformationEvent.Severity.FAILURE));
					}

					public void onSuccess(MyContact contact) {
						display.showAddNewMeeting(contact);
						
					}
				};
				
				backboneRPC.getById(contactid, callback);
			}
		});
		
		display.getMeetingButton().addClickHandler(new ClickHandler() {
			@SuppressWarnings("deprecation")
			public void onClick(ClickEvent event) {
				final String meetingNotes = display.getMeetingNotes().getText();
				
				String[] dateParts = display.getMeetingDate().getText().split("/");
				
				if(meetingNotes.length() > 0 && dateParts.length > 0) {
				
				
					Date date = new Date();
					date.setDate(Integer.parseInt(dateParts[0]));
					date.setMonth((Integer.parseInt(dateParts[1])-1));
					date.setYear((Integer.parseInt(dateParts[2])-1900));
					final long contactid = display.getMeetingContact().getId();
					final int meetingDate = (int)(date.getTime()/1000);
					// Get the user & make sure he is logged in.
					MyUserServiceAsync userRPC = GWT.create(MyUserService.class);
					
					AsyncCallback<MyUser> callback = new AsyncCallback<MyUser>() {
						public void onFailure(Throwable caught) {
							eventBus.fireEvent(new DisplayInformationEvent("Unable to proceed with the request!", DisplayInformationEvent.Severity.FAILURE));
						}
	
						public void onSuccess(MyUser user) {
							// Save new meeting
							AsyncCallback<MyMeeting> callback = new AsyncCallback<MyMeeting>() {
								public void onFailure(Throwable caught) {
								}
	
								public void onSuccess(MyMeeting meeting) {
									display.getMeetingNotes().setText("");
									display.showMeetingSaved(meeting);
									eventBus.fireEvent(new DisplayInformationEvent("Meeting saved successfully!", DisplayInformationEvent.Severity.SUCCESS));
									
								}
							};
							MyMeeting meeting = new MyMeeting(user.getEmail(), contactid, meetingDate, meetingNotes);
							backboneRPC.saveMeeting(meeting, callback);
							
						}
					};
					
					userRPC.getUser(callback);
				} else {
					Window.alert("All fields are required");
				}
			}
		});
	}

	
	
	/**
	 * Main function to update the content of the container.
	 */
	public void updateContent() {
		
		
		AsyncCallback<ArrayList<MyContact>> callback = new AsyncCallback<ArrayList<MyContact>>() {
			public void onFailure(Throwable caught) {
				eventBus.fireEvent(new DisplayInformationEvent("Unable to proceed with the request!", DisplayInformationEvent.Severity.FAILURE));
			}

			public void onSuccess(ArrayList<MyContact> contacts) {
				
				display.setData(contacts);
				
			}
		};
		backboneRPC.fetchContacts(user, null, callback);
	}
}

